home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / source / dialogs / font.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-02  |  11.3 KB  |  363 lines

  1. /*
  2.  * FONT.C
  3.  *
  4.  * Code demonstrating the various uses of the ChooseFont common dialog.
  5.  *
  6.  * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  7.  *
  8.  * Kraig Brockschmidt, Software Design Engineer
  9.  * Microsoft Systems Developer Relations
  10.  * One Microsoft Way
  11.  * Redmond, WA  98052
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  70750,2344
  15.  * Fax       :  (206)936-7329
  16.  */
  17.  
  18. #include <windows.h>
  19. #include <commdlg.h>
  20. #include <dlgs.h>
  21. #include <memory.h>
  22. #include "dialogs.h"
  23.  
  24.  
  25. //Contains the last choice of the user in the Font dialog
  26. HANDLE          hgFont=NULL;
  27. COLORREF        crgFont=0L;
  28.  
  29.  
  30. //Flags of selected font types.
  31. DWORD           dwFlags=CF_SCREENFONTS;
  32.  
  33.  
  34. /*
  35.  * These are global so our hook can use it and so they don't go out of
  36.  * scope when we're executing a modeless variation.
  37.  */
  38. CHOOSEFONT      cf;
  39. LOGFONT         lf;
  40.  
  41.  
  42.  
  43.  
  44.  
  45. /*
  46.  * FontDialogs
  47.  *
  48.  * Purpose:
  49.  *  Invokes variations on the ChooseFont common dialog depending
  50.  *  on the menu selection.  After closing, we create the selected
  51.  *  font and save a handle to it for use in the Print dialogs.
  52.  *
  53.  * Parameters:
  54.  *  hWndOwner       HWND to use as the owner of the dialog.
  55.  *  iDialog         WORD indicating which dialog variation to invoke.
  56.  *  dwFlags         DWORD flags to use to select which fonts are shown.
  57.  *
  58.  * Return Value:
  59.  *  BOOL            TRUE if OK was used in the dialog, FALSE otherwise.
  60.  */
  61.  
  62. BOOL PASCAL FontDialogs(HWND hWndOwner, WORD iDialog, DWORD dwFlags)
  63.     {
  64.     static BOOL     fModeless=FALSE;
  65.     BOOL            fRet=FALSE;
  66.  
  67.     //Prevent reentrancy
  68.     if (fModeless)
  69.         {
  70.         MessageBox(hWndOwner, "Font Dialog is already open", "ChooseFont", MB_OK);
  71.         return FALSE;
  72.         }
  73.  
  74.  
  75.     /*
  76.      * If the combination of flags (in dwFlags) is such that no fonts
  77.      * would show, then ChooseFont will display a message reading
  78.      * "No fonts installed.  Run Control Panel to install fonts."
  79.      */
  80.  
  81.  
  82.     /*
  83.      * Standard initialization:  NULL all the fields in the CHOOSEFONT
  84.      * structure, set lStructSize, set hwndOwner (optional, but typically
  85.      * what you want), and set lpLogFont to point to a valid LOGFONT
  86.      * structure lest ye GP Fault.
  87.      */
  88.     memset(&cf, 0, sizeof(CHOOSEFONT));
  89.     cf.lStructSize=sizeof(CHOOSEFONT);
  90.     cf.hwndOwner=hWndOwner;
  91.     cf.lpLogFont=&lf;
  92.  
  93.     /*
  94.      * For cases below where we use the CF_INITTOLOGFONT structure, we
  95.      * need some information in the LOGFONT struct to use as initializers:
  96.      *
  97.      *  lfFaceName      Initial face name, ignored if CF_NOFACESEL is set.
  98.      *
  99.      *  lfHeight        Initial point size, ignored if CF_NOSIZESEL is set.
  100.      *
  101.      *  lfItalic        Initial font attributes, ignored if CF_NOSTYLESEL
  102.      *  lfBold          is set.  You can also initialize the style with
  103.      *                  the lpszStyle string in the CHOOSEFONT structure and
  104.      *                  the CF_USESTYLE flag, but that option is not exercised
  105.      *                  in this code.
  106.      *
  107.      *  lfStrikeout     Initial state of the Strikeout checkbox if CF_EFFECTS
  108.      *                  is used.
  109.      *
  110.      *  lfUnderline     Initial state of the Underline checkbox if CF_EFFECTS
  111.      *                  is used.
  112.      *
  113.      *
  114.      * Our defaults will be 10pt Times New Roman bold underlined
  115.      */
  116.     lstrcpy(lf.lfFaceName, "Times New Roman");
  117.     lf.lfHeight=10;
  118.     lf.lfItalic=FALSE;
  119.     lf.lfWeight=FW_BOLD;
  120.     lf.lfStrikeOut=FALSE;
  121.     lf.lfUnderline=TRUE;
  122.  
  123.     /*
  124.      * Initial color default, shown as Fuschia in the color combobox when
  125.      * CF_EFFECTS is set.
  126.      */
  127.     cf.rgbColors=RGB(255, 0, 255);
  128.  
  129.  
  130.  
  131.     /*
  132.      * If dwFlags contains CF_PRINTERFONTS, we need an hDC to specify
  133.      * the printer.  We get one by calling PrintDlg (COMMDLG.DLL) with
  134.      * PD_RETURNDEFAULT to get a DC for the default printer.
  135.      */
  136.     if (CF_PRINTERFONTS & dwFlags)
  137.         {
  138.         PRINTDLG        pd;
  139.  
  140.         memset(&pd, 0, sizeof(PRINTDLG));
  141.         pd.lStructSize=sizeof(PRINTDLG);
  142.         pd.Flags =PD_RETURNDC | PD_RETURNDEFAULT;
  143.  
  144.         //If there's no default printer, PrintDlg will fail.
  145.         if (!PrintDlg(&pd))
  146.             {
  147.             MessageBox(hWndOwner, "Cannot use printer fonts:  no default printer."
  148.                        , "ChooseFont", MB_OK);
  149.             return FALSE;
  150.             }
  151.  
  152.         //Cleanup.  See code in PRINT.C for more information.
  153.         if (NULL!=pd.hDevMode)
  154.             GlobalFree(pd.hDevMode);
  155.  
  156.         if (NULL!=pd.hDevNames)
  157.             GlobalFree(pd.hDevNames);
  158.  
  159.         cf.hDC=pd.hDC;
  160.         }
  161.  
  162.  
  163.     switch (iDialog)
  164.         {
  165.         case IDM_FONTBASIC:
  166.             /*
  167.              * For a functional dialog, we set the appropriate fields in
  168.              * the LOGFONT structure as above and use CD_INITTOLOGFONTSTRUCT.
  169.              * CF_FORCEFONTEXIST causes ChooseFont to fail if the font
  170.              * is not actually available.
  171.              */
  172.             cf.Flags=dwFlags | CF_INITTOLOGFONTSTRUCT | CF_FORCEFONTEXIST;
  173.             fRet=ChooseFont(&cf);
  174.             break;
  175.  
  176.  
  177.         case IDM_FONTEFFECTS:
  178.             /*
  179.              * For CF_EFFECTS, we make sure, as above, to initialize the
  180.              * LOGFONT's lfStrikeOut and lfUnderline fields as well as specifying
  181.              * an initial color in cf.rgbColors.
  182.              */
  183.             cf.Flags=dwFlags | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;
  184.             fRet=ChooseFont(&cf);
  185.             break;
  186.  
  187.  
  188.         case IDM_FONTHOOKEDHIDECOLOR:
  189.             /*
  190.              * In the hook procedure we hide the color controls, so we make
  191.              * sure to specify the best default color here.
  192.              */
  193.             cf.rgbColors=GetSysColor(COLOR_WINDOWTEXT);
  194.  
  195.             cf.Flags=dwFlags | CF_EFFECTS | CF_SHOWHELP
  196.                              | CF_INITTOLOGFONTSTRUCT | CF_ENABLEHOOK;
  197.  
  198.             //DLGHOOKPROC is defined in dialogs.h
  199.             cf.lpfnHook=(DLGHOOKPROC)MakeProcInstance(FontHook, hgInst);
  200.  
  201.             fRet=ChooseFont(&cf);
  202.  
  203.             FreeProcInstance((FARPROC)cf.lpfnHook);
  204.             break;
  205.  
  206.  
  207.         case IDM_FONTMODELESS:
  208.             /*
  209.              * We do everything as before setting up a hook, but we use
  210.              * lCustData to pass the owning window handle and leave
  211.              * hwndOwner NULL.  We pass the window handle so we can position
  212.              * ourselves relative to the window at the same postion that the
  213.              * dialog will, by default, be positioned relative to the screen.
  214.              */
  215.             cf.lCustData=hWndOwner;
  216.             cf.hwndOwner=CreateWindow("ModelessPopup", "Parent"
  217.                       , WS_POPUP
  218.                       , 0, 0, 100, 100
  219.                       , hWndOwner, NULL, hgInst, NULL);
  220.  
  221.  
  222.             /*
  223.              * The hook will process the Apply button and send a message
  224.              * to the popup which will recreate and repaint the font
  225.              * in the top-level window.  DLGHOOKPROC is defined in dialogs.h
  226.              */
  227.             cf.lpfnHook=(DLGHOOKPROC)MakeProcInstance(FontHook, hgInst);
  228.  
  229.             //CF_APPLY shows an Apply button that we process in the hook.
  230.             cf.Flags=dwFlags | CF_EFFECTS | CF_INITTOLOGFONTSTRUCT
  231.                              | CF_ENABLEHOOK | CF_APPLY;
  232.  
  233.             fModeless=TRUE;
  234.             fRet=ChooseFont(&cf);
  235.             fModeless=FALSE;
  236.  
  237.             FreeProcInstance((FARPROC)cf.lpfnHook);
  238.             DestroyWindow(cf.hwndOwner);
  239.             break;
  240.  
  241.         }
  242.  
  243.     //Must clean up after PrintDlg.
  244.     if (NULL!=cf.hDC)
  245.         DeleteDC(cf.hDC);
  246.  
  247.     //If we pressed OK, then create the font for later use.
  248.     if (fRet)
  249.         {
  250.         if (NULL!=hgFont)
  251.             DeleteObject(hgFont);
  252.  
  253.         hgFont=CreateFontIndirect(&lf);
  254.  
  255.         //Remember the color as well.
  256.         crgFont=cf.rgbColors;
  257.         }
  258.  
  259.     return fRet;
  260.     }
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268. /*
  269.  * FontHook
  270.  *
  271.  * Purpose:
  272.  *  Dialog procedure hook for the ChooseFont dialogs.  We use the
  273.  *  hook to hide the color combobox and to process the Apply button.
  274.  *
  275.  * Parameters:
  276.  *  Standard parameter list for a dialog box.
  277.  *
  278.  * Return Value:
  279.  *  UINT            Non-Zero or Zero, indicating if the common dialog should
  280.  *                  SKIP the message (non-zero) or not (zero).  Don't confuse
  281.  *                  with typical dialog box return values.
  282.  */
  283.  
  284. UINT FAR PASCAL FontHook(HWND hDlg, UINT iMsg, UINT wParam, LONG lParam)
  285.     {
  286.     static HWND         hWndTop;
  287.     RECT                rc;
  288.     POINT               pt;
  289.     UINT                i;
  290.  
  291.     switch (iMsg)
  292.         {
  293.         case WM_INITDIALOG:
  294.             if (0L==cf.lCustData)
  295.                 {
  296.                 //Hide the color controls in the IDM_FONTHOOKEDHIDECOLOR case.
  297.                 ShowWindow(GetDlgItem(hDlg, stc4), SW_HIDE);
  298.                 ShowWindow(GetDlgItem(hDlg, cmb4), SW_HIDE);
  299.                 hWndTop=NULL;
  300.                 }
  301.             else
  302.                 {
  303.                 /*
  304.                  * Reposition the window relative to the parent whose
  305.                  * handle is in LOWORD(cf.lCustData)
  306.                  */
  307.                 hWndTop=LOWORD(cf.lCustData);
  308.                 pt.x=0;
  309.                 pt.y=0;
  310.                 ClientToScreen(hWndTop, &pt);
  311.                 GetWindowRect(hDlg, &rc);
  312.  
  313.                 SetWindowPos(hDlg, NULL, pt.x+rc.left, pt.y+rc.top
  314.                              , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  315.  
  316.                 //Change OK to Close
  317.                 SetDlgItemText(hDlg, IDOK, "Close");
  318.                 }
  319.             return TRUE;
  320.  
  321.  
  322.         //This is only used in the modeless case as hWndTop is NULL otherwise.
  323.         case WM_COMMAND:
  324.             if (NULL==hWndTop)
  325.                 break;
  326.  
  327.             switch (LOWORD(wParam))
  328.                 {
  329.                 case psh3:  //Apply button
  330.                     //Treat this like we pressed OK in a modal case.
  331.                     if (NULL!=hgFont)
  332.                         DeleteObject(hgFont);
  333.  
  334.                     /*
  335.                      * Ask the dialog for the LOGFONT structure through
  336.                      * the new WM_CHOOSEFONT_GETLOGFONT message documented
  337.                      * in the Windows 3.1 SDK.
  338.                      */
  339.                     SendMessage(hDlg, WM_CHOOSEFONT_GETLOGFONT, 0, (LONG)(LPSTR)&lf);
  340.                     hgFont=CreateFontIndirect(&lf);
  341.  
  342.                     /*
  343.                      * Although currently undocumented, the OFFICIAL method to
  344.                      * retrieve the current color in the color combobox is to
  345.                      * use CB_GETITEMDATA which returns the RGB color for the
  346.                      * specified item that we retrieve with CB_GETCURSEL.
  347.                      */
  348.                     i=(UINT)SendDlgItemMessage(hDlg, cmb4, CB_GETCURSEL, 0, 0L);
  349.  
  350.                     if (CB_ERR!=i)
  351.                         crgFont=SendDlgItemMessage(hDlg, cmb4, CB_GETITEMDATA, i, 0L);
  352.  
  353.                     //Instruct the top-level window to repaint.
  354.                     InvalidateRect(hWndTop, NULL, TRUE);
  355.                     UpdateWindow(hWndTop);
  356.                     return TRUE;
  357.                 }
  358.             break;
  359.         }
  360.  
  361.     return FALSE;
  362.     }
  363.